package biolabs.core

/**
 * Common ancestor for {@link Interaction}s and {@link UnaryAction}s.
 *
 * <p>Represents an action performed on an object in the experiment.
 * Actions are performed while the simulation is paused. They take
 * no simulation time. They typically change the internal state
 * of the target object and/or its children.</p>
 *
 * <p>An action may yield a result. If it does, specify the type of
 * the result in the type parameter {@code R}. If it yields no result,
 * use {@code Unit} in place of {@code R}. After the action completes,
 * its result value is processed by all applicable <i>result handlers</i>.
 * A result handler is a method of the initiating object marked by the
 * {@link ResultHandler} annotation. A result handler is applicable if
 * its action type is assignable from this action.<p>
 *
 * <p>An action may produce intermediate (partial) results and use them
 * to notify the initiating object about the progress. Type of the partial
 * results is specified by the type parameter {@code P}. Each partial
 * result is handed to all applicable <i>progress approvers</i> for
 * approval. A progress approver is a method of the initiating object
 * marked by the {@link ProgressApprover} annotation. A progress approver
 * is applicable if its action type is assignable from this action.
 * A progress approver can reject an individual intermediate result, or
 * cancel the whole action. If this happens, the action should react
 * accordingly, i.e. either omit the current progress or stop completely.</p>
 *
 * @tparam T type of the parent bio-object that initiates the action.
 * @tparam P type of partial result (for progress notifications). May be Unit.
 * @tparam R type of the final action result. May be Unit.
 *
 * @author Tomas Mikula
 */
abstract trait Action[T, P, R]